package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"runtime"
	"syscall"
	"time"

	modbus "gitee.com/barryzxy/gomodbus"
)

// 生产环境Modbus客户端示例
// 展示企业级部署所需的完整配置和最佳实践

func main() {
	fmt.Println("=== 生产环境 Modbus 客户端配置示例 ===")
	fmt.Println("此示例展示企业级生产环境的完整配置和最佳实践")

	// 1. 生产环境配置
	fmt.Println("\n🏭 生产环境配置初始化...")
	config := createProductionConfig()
	displayConfiguration(config)

	// 2. 创建生产级客户端
	fmt.Println("\n🚀 创建生产级客户端...")
	client := createProductionClient(config)

	// 3. 设置监控和健康检查
	fmt.Println("\n📊 设置监控和健康检查...")
	monitor := setupMonitoring(client)
	defer monitor.Close()

	// 4. 设置优雅停机
	fmt.Println("\n⚙️  设置优雅停机处理...")
	ctx, cancel := setupGracefulShutdown()
	defer cancel()

	// 5. 执行生产环境连接
	fmt.Println("\n🔌 建立生产环境连接...")
	err := establishProductionConnection(client, config)
	if err != nil {
		log.Fatalf("生产环境连接失败: %v", err)
	}
	defer client.Close()

	// 6. 启动生产业务逻辑
	fmt.Println("\n📈 启动生产业务逻辑...")
	businessLogic := startBusinessLogic(ctx, client, config)

	// 7. 启动健康检查
	fmt.Println("\n🏥 启动健康检查服务...")
	healthChecker := startHealthCheck(ctx, client, monitor)

	// 8. 启动性能监控
	fmt.Println("\n📊 启动性能监控...")
	performanceMonitor := startPerformanceMonitoring(ctx, client)

	// 9. 主运行循环
	fmt.Println("\n🔄 进入生产运行状态...")
	fmt.Println("💡 按 Ctrl+C 进行优雅停机")

	runProductionLoop(ctx, client, monitor, config)

	// 10. 优雅停机
	fmt.Println("\n🛑 执行优雅停机...")
	gracefulShutdown(businessLogic, healthChecker, performanceMonitor, client)

	fmt.Println("✅ 生产环境客户端已安全关闭")
}

// ProductionConfig 生产环境配置
type ProductionConfig struct {
	// 连接配置
	ServerAddress  string
	ConnectTimeout time.Duration
	ReadTimeout    time.Duration
	WriteTimeout   time.Duration

	// 重试配置
	EnableAutoRetry bool
	MaxRetries      int
	RetryDelay      time.Duration
	RetryBackoff    float64

	// 性能配置
	MaxConcurrency int
	PoolSize       int
	MemoryLimitMB  int

	// 监控配置
	EnableMonitoring    bool
	MetricsInterval     time.Duration
	HealthCheckInterval time.Duration
	AlertThresholds     AlertThresholds

	// 日志配置
	LogLevel    string
	LogFormat   string
	LogRotation bool

	// 安全配置
	EnableTLS bool
	CertFile  string
	KeyFile   string
	CAFile    string
}

// AlertThresholds 告警阈值配置
type AlertThresholds struct {
	MaxErrorRate    float64
	MaxResponseTime time.Duration
	MaxMemoryUsage  int64
	MinSuccessRate  float64
}

// createProductionConfig 创建生产环境配置
func createProductionConfig() *ProductionConfig {
	return &ProductionConfig{
		// 连接配置
		ServerAddress:  getEnv("MODBUS_SERVER", "production-modbus.company.com:502"),
		ConnectTimeout: getDurationEnv("MODBUS_CONNECT_TIMEOUT", 30*time.Second),
		ReadTimeout:    getDurationEnv("MODBUS_READ_TIMEOUT", 10*time.Second),
		WriteTimeout:   getDurationEnv("MODBUS_WRITE_TIMEOUT", 5*time.Second),

		// 重试配置
		EnableAutoRetry: getBoolEnv("MODBUS_AUTO_RETRY", true),
		MaxRetries:      getIntEnv("MODBUS_MAX_RETRIES", 3),
		RetryDelay:      getDurationEnv("MODBUS_RETRY_DELAY", 1*time.Second),
		RetryBackoff:    getFloatEnv("MODBUS_RETRY_BACKOFF", 2.0),

		// 性能配置
		MaxConcurrency: getIntEnv("MODBUS_MAX_CONCURRENCY", runtime.NumCPU()*4),
		PoolSize:       getIntEnv("MODBUS_POOL_SIZE", 50),
		MemoryLimitMB:  getIntEnv("MODBUS_MEMORY_LIMIT_MB", 256),

		// 监控配置
		EnableMonitoring:    getBoolEnv("MODBUS_ENABLE_MONITORING", true),
		MetricsInterval:     getDurationEnv("MODBUS_METRICS_INTERVAL", 30*time.Second),
		HealthCheckInterval: getDurationEnv("MODBUS_HEALTH_INTERVAL", 60*time.Second),
		AlertThresholds: AlertThresholds{
			MaxErrorRate:    getFloatEnv("MODBUS_MAX_ERROR_RATE", 0.05),
			MaxResponseTime: getDurationEnv("MODBUS_MAX_RESPONSE_TIME", 5*time.Second),
			MaxMemoryUsage:  getInt64Env("MODBUS_MAX_MEMORY_USAGE", 200*1024*1024),
			MinSuccessRate:  getFloatEnv("MODBUS_MIN_SUCCESS_RATE", 0.95),
		},

		// 日志配置
		LogLevel:    getEnv("MODBUS_LOG_LEVEL", "INFO"),
		LogFormat:   getEnv("MODBUS_LOG_FORMAT", "JSON"),
		LogRotation: getBoolEnv("MODBUS_LOG_ROTATION", true),

		// 安全配置
		EnableTLS: getBoolEnv("MODBUS_ENABLE_TLS", false),
		CertFile:  getEnv("MODBUS_CERT_FILE", ""),
		KeyFile:   getEnv("MODBUS_KEY_FILE", ""),
		CAFile:    getEnv("MODBUS_CA_FILE", ""),
	}
}

// displayConfiguration 显示配置信息
func displayConfiguration(config *ProductionConfig) {
	fmt.Println("📋 生产环境配置详情：")
	fmt.Printf("  🌐 服务器地址: %s\n", config.ServerAddress)
	fmt.Printf("  ⏱️  连接超时: %v\n", config.ConnectTimeout)
	fmt.Printf("  📖 读取超时: %v\n", config.ReadTimeout)
	fmt.Printf("  ✏️  写入超时: %v\n", config.WriteTimeout)
	fmt.Printf("  🔄 自动重试: %v (最大%d次)\n", config.EnableAutoRetry, config.MaxRetries)
	fmt.Printf("  🚀 最大并发: %d\n", config.MaxConcurrency)
	fmt.Printf("  💾 内存限制: %d MB\n", config.MemoryLimitMB)
	fmt.Printf("  📊 监控: %v\n", config.EnableMonitoring)
	fmt.Printf("  🔒 TLS: %v\n", config.EnableTLS)
	fmt.Printf("  📝 日志级别: %s\n", config.LogLevel)
}

// createProductionClient 创建生产级客户端
func createProductionClient(config *ProductionConfig) modbus.Client {
	// 创建TCP Provider
	provider := modbus.NewTCPClientProvider(config.ServerAddress,
		modbus.WithEnableLogger())

	// 创建客户端with生产配置
	client := modbus.NewClient(provider,
		modbus.WithAutoRetry(config.EnableAutoRetry),
		modbus.WithMaxRetries(config.MaxRetries),
		modbus.WithRetryDelay(config.RetryDelay),
		modbus.WithEnhancedErrorHandling(true),
	)

	fmt.Println("✅ 生产级客户端创建成功")
	fmt.Println("🛡️  启用功能:")
	fmt.Println("  - 自动重连和重试")
	fmt.Println("  - 增强错误处理")
	fmt.Println("  - 连接池管理")
	fmt.Println("  - 内存优化")
	fmt.Println("  - 并发安全保证")

	return client
}

// ProductionMonitor 生产环境监控器
type ProductionMonitor struct {
	client       modbus.Client
	config       *ProductionConfig
	metrics      *ProductionMetrics
	alertManager *AlertManager
	ctx          context.Context
	cancel       context.CancelFunc
}

// ProductionMetrics 生产环境指标
type ProductionMetrics struct {
	TotalRequests     int64
	SuccessRequests   int64
	FailedRequests    int64
	TotalResponseTime time.Duration
	MaxResponseTime   time.Duration
	MinResponseTime   time.Duration
	CurrentMemoryMB   int64
	PeakMemoryMB      int64
	ErrorRate         float64
	SuccessRate       float64
	LastUpdate        time.Time
}

// AlertManager 告警管理器
type AlertManager struct {
	thresholds AlertThresholds
	alerts     []Alert
}

// Alert 告警信息
type Alert struct {
	Type      string
	Message   string
	Level     string
	Timestamp time.Time
	Value     interface{}
}

// setupMonitoring 设置监控
func setupMonitoring(client modbus.Client) *ProductionMonitor {
	ctx, cancel := context.WithCancel(context.Background())

	monitor := &ProductionMonitor{
		client:  client,
		metrics: &ProductionMetrics{},
		ctx:     ctx,
		cancel:  cancel,
	}

	fmt.Println("✅ 监控系统初始化完成")
	return monitor
}

// Close 关闭监控
func (pm *ProductionMonitor) Close() {
	if pm.cancel != nil {
		pm.cancel()
	}
}

// setupGracefulShutdown 设置优雅停机
func setupGracefulShutdown() (context.Context, context.CancelFunc) {
	ctx, cancel := context.WithCancel(context.Background())

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		<-sigChan
		fmt.Println("\n🛑 接收到停机信号...")
		cancel()
	}()

	return ctx, cancel
}

// establishProductionConnection 建立生产环境连接
func establishProductionConnection(client modbus.Client, config *ProductionConfig) error {
	fmt.Println("🔄 尝试建立生产环境连接...")

	maxAttempts := 3
	for attempt := 1; attempt <= maxAttempts; attempt++ {
		fmt.Printf("  尝试连接 #%d/%d...\n", attempt, maxAttempts)

		err := client.Connect()
		if err == nil {
			fmt.Println("✅ 连接建立成功")
			return nil
		}

		fmt.Printf("  ❌ 连接失败: %v\n", err)
		if attempt < maxAttempts {
			delay := time.Duration(attempt) * config.RetryDelay
			fmt.Printf("  ⏳ %v后重试...\n", delay)
			time.Sleep(delay)
		}
	}

	return fmt.Errorf("经过%d次尝试后连接失败", maxAttempts)
}

// startBusinessLogic 启动业务逻辑
func startBusinessLogic(ctx context.Context, client modbus.Client, config *ProductionConfig) chan struct{} {
	done := make(chan struct{})

	go func() {
		defer close(done)

		ticker := time.NewTicker(5 * time.Second)
		defer ticker.Stop()

		operationCount := 0

		for {
			select {
			case <-ctx.Done():
				fmt.Println("📈 业务逻辑正在停止...")
				return
			case <-ticker.C:
				operationCount++

				// 执行业务操作
				err := performBusinessOperation(client, operationCount)
				if err != nil {
					fmt.Printf("⚠️  业务操作 #%d 失败: %v\n", operationCount, err)
				} else {
					if operationCount%10 == 0 {
						fmt.Printf("✅ 业务操作 #%d 完成\n", operationCount)
					}
				}
			}
		}
	}()

	fmt.Println("✅ 业务逻辑已启动")
	return done
}

// performBusinessOperation 执行业务操作
func performBusinessOperation(client modbus.Client, operationID int) error {
	// 模拟典型的业务操作序列
	operations := []func() error{
		func() error {
			// 读取传感器数据
			_, err := client.ReadInputRegisters(1, 0, 10)
			return err
		},
		func() error {
			// 读取设备状态
			_, err := client.ReadCoils(1, 0, 16)
			return err
		},
		func() error {
			// 更新控制参数
			return client.WriteSingleRegister(1, 100, uint16(operationID%1000))
		},
		func() error {
			// 控制设备开关
			return client.WriteSingleCoil(1, 0, operationID%2 == 0)
		},
	}

	// 执行操作序列
	for i, op := range operations {
		err := op()
		if err != nil {
			return fmt.Errorf("业务操作步骤%d失败: %w", i+1, err)
		}
	}

	return nil
}

// startHealthCheck 启动健康检查
func startHealthCheck(ctx context.Context, client modbus.Client, monitor *ProductionMonitor) chan struct{} {
	done := make(chan struct{})

	go func() {
		defer close(done)

		ticker := time.NewTicker(30 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ctx.Done():
				fmt.Println("🏥 健康检查服务正在停止...")
				return
			case <-ticker.C:
				healthy := performHealthCheck(client)
				if healthy {
					fmt.Println("✅ 健康检查通过")
				} else {
					fmt.Println("❌ 健康检查失败")
					// 在生产环境中，这里会触发告警
				}
			}
		}
	}()

	fmt.Println("✅ 健康检查服务已启动")
	return done
}

// performHealthCheck 执行健康检查
func performHealthCheck(client modbus.Client) bool {
	// 执行简单的连接性测试
	_, err := client.ReadHoldingRegisters(1, 0, 1)
	return err == nil
}

// startPerformanceMonitoring 启动性能监控
func startPerformanceMonitoring(ctx context.Context, client modbus.Client) chan struct{} {
	done := make(chan struct{})

	go func() {
		defer close(done)

		ticker := time.NewTicker(60 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ctx.Done():
				fmt.Println("📊 性能监控正在停止...")
				return
			case <-ticker.C:
				collectPerformanceMetrics(client)
			}
		}
	}()

	fmt.Println("✅ 性能监控已启动")
	return done
}

// collectPerformanceMetrics 收集性能指标
func collectPerformanceMetrics(client modbus.Client) {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)

	memoryMB := int64(m.Alloc / 1024 / 1024)
	goroutines := runtime.NumGoroutine()

	fmt.Printf("📊 性能指标: 内存=%dMB, 协程=%d, GC次数=%d\n",
		memoryMB, goroutines, m.NumGC)
}

// runProductionLoop 运行生产循环
func runProductionLoop(ctx context.Context, client modbus.Client, monitor *ProductionMonitor, config *ProductionConfig) {
	ticker := time.NewTicker(10 * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			// 显示运行状态
			showProductionStatus(client, monitor)
		}
	}
}

// showProductionStatus 显示生产状态
func showProductionStatus(client modbus.Client, monitor *ProductionMonitor) {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)

	fmt.Printf("🔄 生产状态: 内存=%dMB, 协程=%d, 运行时间=%v\n",
		m.Alloc/1024/1024,
		runtime.NumGoroutine(),
		time.Since(time.Now().Truncate(24*time.Hour)))
}

// gracefulShutdown 优雅停机
func gracefulShutdown(businessLogic, healthChecker, performanceMonitor chan struct{}, client modbus.Client) {
	fmt.Println("⏳ 等待业务逻辑完成...")
	<-businessLogic

	fmt.Println("⏳ 等待健康检查停止...")
	<-healthChecker

	fmt.Println("⏳ 等待性能监控停止...")
	<-performanceMonitor

	fmt.Println("🔌 关闭客户端连接...")
	// client.Close() 会在defer中调用
}
